
exports.use_role_card = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.rid) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }
        var rid = +req.args.rid;
        var user = player.user;
        
        if( !player.canEnrollRole(rid) ) {
            resp.code = 1; resp.desc = 'role exist or full'; break;
        }

        if( !player.addRoleCard(rid, -1) ) {
            resp.code = 1; resp.desc = 'no more card'; break;
        }

        var role = player.addRole(rid);
        resp.data.role = role;
    }while(false);

    onHandled();
}

exports.kill_role_card = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.rid) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }
        var rid = +req.args.rid;

        var user = player.user;
        
        var existCardNum = user.role_card[rid];
        if( !existCardNum || existCardNum <= 0 ) {
            resp.code = 1; resp.desc = 'no more card'; break;
        }
        
        var addSoul = gConfGlobal['RoleToSoul'+gConfRole[rid].Quantity];
        user.role_card[rid] -= 1;
        player.markDirty('role_card.'+rid);

        user.status.soul += addSoul;
        player.markDirty('status.soul');

        resp.data.soul = addSoul;
    }while(false);

    onHandled();
}

exports.buy = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.id) || isNaN(req.args.num) || !gConfShop[req.args.id] ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var id = +req.args.id;
        var num = parseInt(req.args.num);

        if (num < 1 || num > 999) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }


        var user = player.user;
        var ride = user.ride; 

        var shopConf = gConfShop[id];
        // 开服时间限制
        //if( (shopConf.OpenDays * 86400 + gConfGlobalServer.ServerStartTime) > common.getTime() ) {
        //    resp.code = 1; resp.desc = 'time limit'; break;
        //}

        var costType = shopConf.Currency;
        var costNum = (+shopConf.Price) * num;
        
        if( ( 'cash' == costType || 'honor' == costType) 
            && (user.status[costType] < costNum) ) {
            resp.code = 1; resp.desc = 'not enough currency'; break;
        }else if( 'horse' == costType && ( ride.horse_currency < costNum ) ) {
            resp.code = 1; resp.desc = 'not enough horse'; break;
        }
        
        var awards = [];    // 购买结果,用award格式返回
        if( shopConf.Category1 == 'equip' ) {
            for( var i=0; i<num; i++ ) {
                var equip = player.addEquip(shopConf.Category2, shopConf.Category3);
                awards.push(['equip', shopConf.Category2, equip]);
            }
        }else if( shopConf.Category1 == 'inventory' ) {
            player.addInventory(shopConf.Category2, shopConf.Category3, num);
            awards.push([shopConf.Category2, shopConf.Category3, num]);
            for( var i = 0; i < num; i++) {
                if( shopConf.Category2 == 'material' ) {
                    player.doTask('ExchangeMaterial',shopConf.Category3);
                } 
            }
        }else{
            resp.code = 1; resp.desc = 'category not support'; break;
        }
        
        if( 'cash' == costType || 'honor' == costType ) {
            player.costResource(costType, costNum, id, num); 
        }else if( 'horse' == costType ) {
            ride.horse_currency -= costNum; 
            player.markDirty('ride.horse_currency');
        }

        if( costType == 'cash' ) {
            // 统计每日商店元宝花费
            var today = common.getDate();
            var dailyShopCost = user.activity.daily_shop_cost;
            if( today != dailyShopCost.day ) {
                dailyShopCost.cash = 0;
                dailyShopCost.day = today;
            }

            dailyShopCost.cash += costNum;
            player.markDirty('activity.daily_shop_cost');
        }

        resp.data.cost_type = costType;
        resp.data.cost_num = -costNum;
        resp.data.awards = awards;
        resp.data.daily_shop_cost = dailyShopCost;

    }while(false);

    onHandled();
}

exports.sell = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.id) || isNaN(req.args.num) || 'string' != typeof(req.args.type) 
            || !('material' == req.args.type || 'equip' == req.args.type
            || 'gem' == req.args.type) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }
        
        var type = req.args.type;
        var id = +req.args.id;
        var num = Math.round(req.args.num);
        if( num < 1 ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var user = player.user;
        var sellGold = 0;

        if( 'material' == type ) {
            if( !gConfMaterial[id] ) {
                resp.code = 1; resp.desc = 'id error'; break;
            } 

            if( player.getInventory('material', id, true) <num ) {
                resp.code = 1; resp.desc = 'num error'; break;
            }
            
            sellGold = num*(+gConfMaterial[id].Sell); 

            player.addInventory('material', id, -num);
        }else if( 'equip' == type ) {
            var equip = user.equip[id];
            if( !equip ) {
                resp.code = 1; resp.desc = 'id error'; break;
            }

            var equipWeard = player.getEquipWeard();
            if( equipWeard[id] ) {
                resp.code = 1; resp.desc = 'weard'; break;
            }

            sellGold = gConfEquip[equip.level].Sell;

            delete user.equip[id];
            player.markDelete('equip.' + id);
        }else if( 'gem' == type ) {
            if( !gConfGem[id] ) {
                resp.code = 1; resp.desc = 'id error'; break;
            }
            
            if( player.getInventory('gem', id) < num ) {
                resp.code = 1; resp.desc = 'num error'; break;
            }
            
            sellGold = num * gConfGem[id].Sell;
            player.addInventory('gem', id, -num);
        }

        user.status.gold += sellGold;
        player.markDirty('status.gold');

        resp.data.gold = sellGold;

    }while(false);

    onHandled();
}

exports.use = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.id) ){
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var num = 1;
        if( !isNaN(req.args.num) ) {
            num = Math.round(req.args.num);  
        }

        if( num <= 0 ) {
            resp.code = 1; resp.desc = 'invalid num'; break;
        }

        var user = player.user;
        
        var id = parseInt(req.args.id);
        var materialConf = gConfMaterial[id];
        if( !materialConf || !materialConf.CanUse ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }
        
        player.checkInventory();
        var ownedMaterialNum = player.getInventory('material', id); 
        if( ownedMaterialNum < 1 ) {
            resp.code = 1; resp.desc = 'not enough'; break;
        }
        
        var costMaterialNum = 1;
        var materialUseType = materialConf.UseType;
        if( materialUseType == 'soul' ){
            // 将魂包
            costMaterialNum = num;
            if( ownedMaterialNum < costMaterialNum ) {
                resp.code = 1; resp.desc = 'not enough'; break;
            }

            var addSoul = materialConf.UseEffect * num;
            user.status.soul += addSoul;
            player.markDirty('status.soul');

            resp.data.soul = addSoul;
        }else if( materialUseType == 'merge' ){
            var mergeRoleId = materialConf.UseEffect; 
            var roleConf = gConfRole[mergeRoleId];
            if( !roleConf || (roleConf.MergeId != id) ) {
                resp.code = 1; resp.desc = 'use effect error'; break;
            }
            
            costMaterialNum = roleConf.MergeNum; 
            if( ownedMaterialNum < costMaterialNum ) {
                resp.code = 1; resp.desc = 'not enough'; break;
            }

            resp.data.awards = player.addAwards([['card',mergeRoleId,1]]);
        
        }else if( materialConf.UseType == 'box') {
            // 使用箱子
            
            var boxConf = gConfBox[id];
            if( !boxConf ) {
                resp.code = 1; resp.desc = 'invalid box id'; break;
            }

            costMaterialNum = num;
            if( ownedMaterialNum < costMaterialNum ) {
                resp.code = 1; resp.desc = 'not enough'; break;
            }

            if( gConfGlobal.RedPacketMaterialId == id ) {
                // 使用红包,限定每天只能使用1个
                var redPacket = user.activity.red_packet; 
                if( (redPacket.open + num) > gConfGlobal.RedPacketDailyUseLimit ) {
                    resp.code = 1; resp.desc = 'invalid use num'; break;
                }
                
                redPacket.open += num;
                player.markDirty('activity.red_packet.open');
            }

            if( gConfGlobal.NewRedPacketMaterialId == id ) {
                // 使用新区红包,限定每天只能使用1个
                var newRedPacket = user.activity.new_red_packet; 
                if( (newRedPacket.open + num) > gConfGlobal.NewRedPacketDailyUseLimit ) {
                    resp.code = 1; resp.desc = 'invalid use num'; break;
                }
                
                newRedPacket.open += num;
                player.markDirty('activity.new_red_packet.open');
            }
            
            var awards = [];
            for( var j=1; j<=num; j++ ) {
                var weights = {};
                for( var i=1; i<=10; i++ ) {
                    if( !boxConf['Weight'+i] ) continue;
                    weights[i] = boxConf['Weight'+i];
                }
                
                for( var i=1; i<= boxConf.Num; i++ ) {
                    var awardId = common.wRand(weights); 
                    awards.push(boxConf['Award'+awardId]);
                    delete weights[awardId];
                }
            }

            awards = player.addAwards(awards);

            resp.data.awards = awards;
        }else if( materialConf.UseType == 'card'){
            // 翻牌箱子
            var cardConf = gConfCard[id];
            if( !cardConf ) {
                resp.code = 1; resp.desc = 'invalid card id'; break;
            }

            var weights = {};
            for( var i=1; i<=9; i++ ) {
                if( !cardConf['Weight'+i] ) continue;
                weights[i] = cardConf['Weight'+i];
            }
            
            var awardId = common.wRand(weights); 
            var awards = [cardConf['Award'+awardId]];

            awards = player.addAwards(awards);
            resp.data.awards = awards;
        }else if( materialConf.UseType == 'combine'){
            // 合成 N物品A -> 1物品B
            costMaterialNum = materialConf.UseNeed;
            if( ownedMaterialNum < costMaterialNum ) {
                resp.code = 1; resp.desc = 'not enough'; break;
            }

            var awards = [['material', materialConf.UseEffect, 1]];
            awards = player.addAwards(awards);
            resp.data.awards = awards;
        }else if( materialConf.UseType == 'pet'){
            // 神兽幻化丹
            costMaterialNum = num;
            if( ownedMaterialNum < costMaterialNum ) {
                resp.code = 1; resp.desc = 'not enough'; break;
            }

            var newPetBuff = (user.pet.buff || 0) + num;
            if( newPetBuff > gConfPet[user.pet.level].BuffNum ) {
                resp.code = 1; resp.desc = 'too much'; break;
            }

            user.pet.buff = newPetBuff;
            player.markDirty('pet.buff');
        } else if (materialConf.UseType == 'composite') {
            // 橙马合成
            costMaterialNum = materialConf.UseNeed;
            if( ownedMaterialNum < costMaterialNum ) {
                resp.code = 1; resp.desc = 'not enough'; break;
            }

            var awards = [['horse', materialConf.UseEffect, 1]];
            awards = player.addAwards(awards);
            resp.data.awards = awards;
        }else if (materialConf.UseType == 'hsoul') {
            // 星魂
            costMaterialNum = num;
            if( ownedMaterialNum < costMaterialNum ) {
                resp.code = 1; resp.desc = 'not enough'; break;
            }

            var awards = [['user', 'hsoul', materialConf.UseEffect * costMaterialNum]];
            awards = player.addAwards(awards);
            resp.data.awards = awards;
        }else{
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        var material = {};
        material[id] = -costMaterialNum;
            
        player.addInventory('material', id, -costMaterialNum);
        resp.data.material = material;
    }while(false);

    onHandled();
}

exports.open_slot = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.id) ){
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var user = player.user;
        
        var id = parseInt(req.args.id);
        var materialConf = gConfMaterial[id];
        if( !materialConf || !materialConf.CanUse 
            || materialConf.UseType != 'slot' || !gConfSlot[id] ) {
            resp.code = 1; resp.desc = 'invalid id'; break;
        }

        if( player.getInventory('material', id) < 1 ) {
            resp.code = 1; resp.desc = 'not enough'; break;
        }
        
        var costMaterialNum = 1;
        if( materialConf.UseType == 'slot' ) {
            // 幸运宝箱
            var weights = {}; 
            var items = gConfSlot[id];
            var awards = [];
            var spcialRewardIndex = 0;
            var mustOpenIndex = 0;
            var mustOpenCount = 0;
            for( var index in items ) {
                var item = items[index];
                if( !item.Random ) {
                    awards.push(item.Award1);
                    continue;
                }

                weights[index] = item.Weight;
                if( item.Open ) {
                    mustOpenIndex = +index;
                    mustOpenCount = item.Open;
                }
            }

            var slot = user.activity.slot; 
            if( !(id in slot) ) {
                slot[id] = 0;
            }
            
            slot[id] += 1;
            if( (mustOpenCount > 0) && (slot[id] >= mustOpenCount) ) {
                slot[id] = 0; 
                spcialRewardIndex = mustOpenIndex; 
            }else {
                spcialRewardIndex = +common.wRand(weights);
            }

            player.markDirty(util.format('activity.slot.%d', id));
            awards.push(items[spcialRewardIndex].Award1);
             
            resp.data.index = spcialRewardIndex;
            resp.data.awards = player.addAwards(awards);
        }else{
            resp.code = 1; resp.desc = 'invalid id'; break;
        }
            
        player.addInventory('material', id, -costMaterialNum);

    }while(false);

    onHandled();

}
